home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / zm16src.lzh / TRANSFER.C < prev    next >
C/C++ Source or Header  |  1988-05-19  |  17KB  |  968 lines

  1. /*
  2.  *     (Quick & Dirty) Transfer Shell
  3.  *
  4.  *        Jwahar Bammi
  5.  *            usenet: mandrill!bammi@{decvax,sun}.UUCP
  6.  *            csnet:  bammi@mandrill.ces.CWRU.edu
  7.  *            arpa:   bammi@mandrill.ces.CWRU.edu
  8.  *            CompuServe: 71515,155
  9.  */
  10.  
  11. #include "config.h"
  12.  
  13. #ifdef DLIBS
  14. #include <string.h>
  15. #endif
  16.  
  17. #include "zmdm.h"
  18. #include "common.h"
  19.  
  20. #define ISWILD(X)    ((X == '*')||(X == '?'))
  21. #define PROMPT        fprintf(STDERR,"zmdm> ")
  22.  
  23. extern int dorz(), dosz(), ls(), rm(), cp(), cd(), md(), rd(), pwd(), df(),
  24.        hhelp();
  25.  
  26. #ifdef RECURSE
  27. extern int doszf();
  28. #endif
  29.  
  30. static struct comnds {
  31.     char    *command;    /* command string    */
  32.     int     (*routine)();    /* routine to invoke    */
  33.     char    *synopsis;    /* synopsis        */
  34.     int    expand;        /* expand wildcards before calling routine? */
  35. } comtab [] = {
  36.     { "rz",    dorz, "receive files using Z/X modem protocol",       TRUE },
  37.     { "rb", dorz, "receive files using Y modem protocol",         TRUE },
  38. #ifdef RECURSE
  39.     { "sz", doszf, "send files using Z/Y/X modem protocol",        TRUE },
  40. #else
  41.     { "sz", dosz, "send files using Z/Y/X modem protocol",        TRUE },
  42. #endif
  43.     { "sb", dosz, "send files using Y modem protocol",            TRUE },
  44.     { "rm", rm,   "remove files",                                 TRUE },
  45.     { "cp", cp,   "copy files",                                   TRUE },
  46.     { "ls", ls,   "list directory",                               FALSE},
  47.     { "cd", cd,   "change working directory",             FALSE},
  48.     { "md", md,   "make a directory",                 FALSE},
  49.     { "rd", rd,   "remove a directory",                     FALSE},
  50.     { "pwd",pwd,  "print  working directory",             FALSE},
  51.     { "df", df,   "check free space",                 FALSE},
  52.     { "?",  hhelp, "this message",                     FALSE},
  53.     { (char *)NULL, (int (*)())NULL, (char *)NULL,                   FALSE}
  54. };
  55.  
  56. #define MAXARGS    1024
  57. static char *targv[MAXARGS];
  58. static int targc;
  59. char *alltolower();
  60.  
  61. transfer()
  62. {
  63.     char linebuf[132];
  64.     char *line;
  65.     int command;
  66.     int status;
  67.     extern int find_command();
  68.     extern int expnd_args();
  69. #ifdef DEBUG
  70.     int i;
  71. #endif
  72.  
  73.     fprintf(STDERR,"hit <RETURN> to return to emulator,  <?> for help\n\n");
  74.     targc = 0;
  75.     while (TRUE)
  76.     {
  77.         if(targc > 1)
  78.             free_args();
  79.  
  80.         PROMPT;
  81.         linebuf[0] = 127;
  82. #ifndef REMOTE
  83.         Cconrs(linebuf);
  84. #else
  85.         Cconraux(linebuf);
  86. #endif
  87.         putc('\n', STDERR);
  88.         if(linebuf[1] == 0)
  89.         /* cancelled */
  90.         return;
  91.         
  92.         linebuf[(linebuf[1]+2)] = '\0';
  93.         line = &linebuf[2];
  94. #ifdef DEBUG
  95. printf("Line: |%s|\n", line);
  96. #endif
  97.  
  98.         targv[0] = line;
  99.         targc    = 1;
  100.     
  101.         /* pick up targv[0] */
  102.         while((*line != '\0') && (!isspace(*line)))
  103.             line++;
  104.  
  105.         if(*line != '\0')
  106.         {
  107.             *line++ = '\0';
  108.         }
  109.  
  110.         if((command = find_command(targv[0])) < 0)
  111.         {
  112.             fprintf(STDERR,"Invalid Command\n");
  113.             continue;
  114.         }
  115.  
  116.         if(expnd_args(line, comtab[command].expand))
  117.             /* too many args */
  118.             continue;
  119. #ifdef DEBUG
  120. printf("targc %d\n", targc);
  121. for(i = 0; i < targc; i++)
  122.     printf("%s ", targv[i]);
  123. printf("\n\n");
  124. #endif
  125.  
  126.         if((status = (*(comtab[command].routine))(targc, targv)) != 0)
  127.             fprintf(STDERR,"Exit Status %d\n", status);
  128.  
  129. #ifdef DEBUG
  130. printf("Exit Status %d\n", status);
  131. #endif
  132.  
  133.     } /* While */
  134. }
  135.  
  136. /*
  137.  * Straight sequential search thru comtab
  138.  */        
  139. int find_command(s)
  140. register char *s;
  141. {
  142.     register int i;
  143.  
  144.     for(i = 0; comtab[i].command != (char *)NULL; i++)
  145.     {
  146.         if(strcmp(s, comtab[i].command) == 0)
  147.             return i;
  148.     }
  149.  
  150.     return -1;
  151. }
  152.  
  153. /*
  154.  * Expand command line args, return TRUE if too many args, or Not matching Quotes
  155.  */
  156. int expnd_args(s, expand_wild)
  157. register char *s;
  158. int expand_wild;
  159. {
  160.     char next_arg[128];
  161.     register char *p;
  162.     register int contains_wild;
  163.     extern int add_argv();
  164.     extern int handl_wild();
  165.  
  166.     while(*s != '\0')
  167.     {
  168.         p = next_arg;
  169.         while(isspace(*s)) s++; /* skip leading space */
  170.         if(*s != '\0')
  171.         {
  172.             contains_wild = FALSE;
  173.             if(*s == '\047')
  174.             {
  175.                 /* Quoted arg */
  176.                 s++;
  177.                 while((*s != '\0') && (*s != '\047'))
  178.                     *p++ = *s++;
  179.                 *p = '\0';
  180.                 if(*s == '\0')
  181.                 {
  182.                     fprintf(STDERR,"No Matching Quote\n");
  183.                     return TRUE;
  184.                 }
  185.                 else
  186.                     s++;
  187.                 if(add_argv(next_arg))
  188.                     return TRUE;
  189.             }
  190.             else
  191.             {
  192.                 while(!isspace(*s) && (*s != '\0'))
  193.                 {
  194.                     contains_wild |= ISWILD(*s);
  195.                     *p++ = *s++;
  196.                 }
  197.                 *p = '\0';
  198.  
  199.                 if(contains_wild && expand_wild)
  200.                 {
  201.                     if(handl_wild(next_arg))
  202.                         return TRUE;
  203.                 }
  204.                 else
  205.                 {
  206.                     if(add_argv(next_arg))
  207.                         return TRUE;
  208.                 }
  209.             } /* if-else */
  210.         } /* If */
  211.     } /* while */
  212.  
  213.     return FALSE;
  214. }
  215.  
  216. /*
  217.  * add an arg to argv. Return TRUE if error
  218.  */
  219. int add_argv(s)
  220. char *s;
  221. {
  222.     extern char *myalloc();
  223.     extern char *strcpy();
  224.     extern int strlen();
  225.  
  226.     if(targc > (MAXARGS-1))
  227.     {
  228.         fprintf(STDERR,"Too many arguements (%d Max)\n", MAXARGS);
  229.         return TRUE;
  230.     }
  231.     targv[targc++] = strcpy(myalloc(strlen(s)+1), s);
  232.     
  233.     return FALSE;
  234.     
  235. }
  236.  
  237. /*
  238.  * expand wild card arguments. Return TRUE on error.
  239.  */
  240. int handl_wild(s)
  241. char *s;
  242. {
  243.     extern struct stat statbuf;
  244.     extern char *mkpathname();
  245.     
  246.     if(Fsfirst(s, 0x21) != 0)
  247.     {
  248.         /* No match */
  249.         fprintf(STDERR,"No Match for %s\n", s);
  250.         return TRUE;
  251.     }
  252.  
  253.     alltolower(statbuf.st_name);
  254.     if(add_argv(mkpathname(s, statbuf.st_name)))
  255.         return TRUE;
  256.  
  257.     while(Fsnext() == 0)
  258.     {
  259.         alltolower(statbuf.st_name);
  260.         if(add_argv(mkpathname(s, statbuf.st_name)))
  261.             return TRUE;
  262.     }
  263.  
  264.     return FALSE;
  265. }
  266.  
  267. /*
  268.  * Given a spec with a trailing wildcard and a base will name construct pathname
  269.  *
  270.  */
  271. char *mkpathname(spec, file)
  272. register char *spec, *file;
  273. {
  274.     extern char *rindex();
  275.     register char *p;
  276.  
  277.     if((p = rindex(spec, '\\')) == (char *)NULL)
  278.         /* no path name */
  279.         return file;
  280.  
  281.     while(*file != '\0')
  282.         *++p = *file++;
  283.     *++p = '\0';
  284.     
  285.     return spec;
  286. }
  287.  
  288. free_args()
  289. {
  290.     register int i;
  291.     
  292.     for(i = 1; i < targc; i++)
  293.         free(targv[i]);
  294. }
  295.  
  296. /*
  297.  * remove files
  298.  *    Usage: rm [-i] files ... 
  299.  */    
  300. int rm(argc, argv)
  301. register int argc;
  302. register char **argv;
  303. {
  304.     register int interactive;
  305.     register int status, s;
  306.     extern int yesno();
  307.     extern int errno;
  308.  
  309.     interactive = FALSE;
  310.     status = 0;
  311.     while(--argc)
  312.     {
  313.         ++argv;
  314.         if( ((*argv)[0] == '-') && ((*argv)[1] == 'i') )
  315.             interactive = TRUE;
  316.         else
  317.         {
  318.             if(interactive)
  319.                 if(!yesno("rm: remove", *argv))
  320.                     continue;
  321.             if(unlink(*argv))
  322.             {
  323.                 s |= 1;
  324.                 fprintf(STDERR, "%s: no such file\n", *argv);
  325.             }
  326.             status |= s;
  327.         }
  328.     }
  329.     return status;
  330. }
  331.  
  332. /*
  333.  * Prompt and return Yes/No truth value
  334.  *
  335.  */
  336. int yesno(p1, p2)
  337. register char *p1, *p2;
  338. {
  339.     char reply[16];
  340.  
  341.     fprintf(STDERR,"%s %s (y/n): ", p1, p2);
  342.     reply[0] = 16;
  343. #ifndef REMOTE
  344.     Cconrs(reply);
  345. #else
  346.     Cconraux(reply);
  347. #endif
  348.  
  349.     putc('\n', STDERR);
  350.     return ( (reply[2] == 'y') || (reply[2] == 'Y') );
  351.  
  352. }
  353.  
  354. /*
  355.  * copy files
  356.  *    Usage:
  357.  *        cp src dest
  358.  *        or
  359.  *        cp files.. directory
  360.  */
  361. int cp(argc, argv)
  362. int argc;
  363. char **argv;
  364. {
  365.     char dest[128];
  366.     register int status;
  367.     extern int strlen();
  368.     extern int cpy();
  369.     extern char *basename();
  370.     
  371.     status = 0;
  372.     if(argc > 3)
  373.     {
  374.         register int i;
  375.  
  376.         if(!existd(argv[argc-1]))
  377.         {
  378.             fprintf(STDERR,"%s does not exists or is not a directory\n",
  379.                 argv[argc-1]);
  380.             return 1;
  381.         }
  382.  
  383.         for(i = 1; i < argc - 1; i++)
  384.         {
  385.             strcpy(dest, argv[argc-1]);
  386.             if( (argv[argc-1])[(strlen(argv[argc-1])-1)] != '\\')
  387.                 strcat(dest, "\\");
  388.             strcat(dest, basename(argv[i]));
  389.  
  390.             fprintf(STDERR,"copying %s to %s\n", argv[i], dest);
  391.             status |= cpy(argv[i], dest);
  392.         }
  393.     }
  394.     else
  395.     {
  396.         if(argc > 2)
  397.         {
  398.             if(existd(argv[2]))
  399.             {
  400.                 /* dest is a directory */
  401.                 strcpy(dest, argv[2]);
  402.                 if( (argv[2])[(strlen(argv[2])-1)] != '\\')
  403.                     strcat(dest, "\\");
  404.  
  405.                 strcat(dest, basename(argv[1]));
  406.  
  407.                 fprintf(STDERR,"copying %s to %s\n", argv[1], dest);
  408.                 return (cpy(argv[1], dest));
  409.             }
  410.  
  411.             if(strcmp(argv[1], argv[2]) == 0)
  412.             {
  413.                 fprintf(STDERR,"Cannot copy a file onto itself\n");
  414.                 return 3;
  415.             }
  416.             status = cpy(argv[1], argv[2]);
  417.         }
  418.         else
  419.         {
  420.             fprintf(STDERR,"Usage: cp source dest or cp files .. directory\n");
  421.             return 2;
  422.         }
  423.     }
  424.  
  425.     retur